package com.lndsnx.demo;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import java.security.KeyStore;

/**
 * @Description 连接工厂
 * @Author lndsnx
 * @Date 2025/7/30 上午9:50
 **/
public class ConnectionFactory {
    // 配置信息
    private final String hostName;
    private final int port;
    private final String userName;
    private final String password;
    private final String virtualHost;
    // 是否启用SSL实例变量
    private final boolean enableSSL;

    public ConnectionFactory(String hostName, int port, String userName,
        String password, String virtualHost, boolean enableSSL) {
        this.hostName = hostName;
        this.port = port;
        this.userName = userName;
        this.password = password;
        this.virtualHost = virtualHost;
        this.enableSSL = enableSSL;
    }

    // 创建Channel
    public Channel createChannel() throws Exception {
        // 创建一个新的连接
        Connection con = createCon();

        // 创建一个新的通道
        return con.createChannel();
    }

    /**
     * 创建连接
     */
    private Connection createCon() throws Exception {
        // 创建RabbitMQ官方连接工厂实例
        com.rabbitmq.client.ConnectionFactory factory = new com.rabbitmq.client.ConnectionFactory();

        // 设置主机名
        factory.setHost(hostName);
        // 设置用户名
        factory.setUsername(userName);
        // 设置密码
        factory.setPassword(password);

        // 设置为true，开启Connection自动恢复功能；设置为false，关闭Connection自动恢复功能。
        factory.setAutomaticRecoveryEnabled(true);
        // 设置网络恢复间隔为5000毫秒
        factory.setNetworkRecoveryInterval(5000);
        // 设置虚拟主机
        factory.setVirtualHost(virtualHost);
        // 默认端口。
        factory.setPort(port);

        // 如果启用了SSL，则配置SSL
        if (enableSSL) {
            setSSL(factory);
        }

        // 基于网络环境合理设置超时时间。
        // 设置连接超时时间为30秒
        factory.setConnectionTimeout(30 * 1000);
        // 设置握手超时时间为30秒
        factory.setHandshakeTimeout(30 * 1000);
        // 设置关闭超时时间为0（立即关闭）
        factory.setShutdownTimeout(0);

        // 创建并返回新连接
        return factory.newConnection();
    }

    /**
     * 设置SSL配置
     */
    private void setSSL(
        com.rabbitmq.client.ConnectionFactory factory) throws Exception {
        // 创建TLSv1.2版本的SSL上下文
        SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
        // 获取默认算法的信任管理器工厂
        TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        // 初始化信任管理器工厂，使用默认的密钥库
        trustManagerFactory.init((KeyStore) null);
        // 初始化SSL上下文
        sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
        // 在连接工厂中使用SSL协议
        factory.useSslProtocol(sslContext);
    }

    /**
     * 关闭连接的方法
     */
    public void closeCon(Channel channel) {
        // 检查通道及其连接是否不为null
        if (channel != null && channel.getConnection() != null) {
            try {
                // 关闭连接
                channel.getConnection().close();
            } catch (Throwable t) {
                // 忽略关闭时的异常
            }
        }
    }
}